/**
 *
 */
package soa.security.jpa.service.impl;

import java.io.StringWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;

import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;
import org.springframework.stereotype.Service;

import soa.security.jpa.domain.Change;
import soa.security.jpa.repository.ChangeRepository;
import soa.security.jpa.service.ChangeMgrService;
import soa.security.jpa.service.ChangePolicy;

import com.sun.istack.NotNull;

/**
 * @author Cre.Gu
 *
 */
@Service
public class ChangeMgrServiceImpl implements ChangeMgrService {

	@NotNull
	@Resource
	private ChangePolicy changePolicy;
	@Resource
	private ChangeRepository changeRepository;

	@Override
	public void record(Change change) {
		changePolicy.record(change);
	}

	@Override
	public void save(Change change) {
		Change entity = changeRepository.findByOrganizationIdAndDn(
				change.getOrganizationId(), change.getDn());

		if (entity != null) {
			entity.setDeleted(false);
			entity.setUpdateTime(new Date());

			changeRepository.save(entity);
		} else {
			changeRepository.save(change);
		}
	}

	@Override
	public String buildXml(String organizationId, boolean deleted) {
		List<Change> list = changeRepository
				.findByOrganizationId(organizationId);

		String result = buildXmlInternal(list);

		if (deleted) {
			for (Change change : list) {
				change.setDeleted(true);
			}

			changeRepository.save(list);
		}
		return result;
	}

	private String buildXmlInternal(List<Change> list) {
		String result = "";
		try {
			Document document = DocumentHelper.createDocument();
			Element root = document.addElement("changes");

			Element ele = null, bid = null, updateTime = null;
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

			for (Change change : list) {
				switch (change.getType()) {
				case ACCOUNT:
					ele = root.addElement("account");
					bid = ele.addElement("uid");

					break;
				case ORGANIZATION:
					ele = root.addElement("organization");
					bid = ele.addElement("bid");

					break;
				case DEPARTMENT:
					ele = root.addElement("department");
					bid = ele.addElement("bid");

					break;
				case PERSON:
					ele = root.addElement("person");
					bid = ele.addElement("uid");

					break;
				case POSITION:
					ele = root.addElement("position");
					bid = ele.addElement("bid");

					break;
				case GROUP:
					ele = root.addElement("group");
					bid = ele.addElement("bid");

					break;
				case Applsystem:
					ele = root.addElement("applsystem");
					bid = ele.addElement("bid");

					break;
				default:
					break;
				}

				if (ele == null || bid == null)
					continue;

				bid.addText(change.getBid());

				updateTime = ele.addElement("updateTime");
				updateTime.addText(sdf.format(change.getUpdateTime()));
			}

			OutputFormat format = OutputFormat.createPrettyPrint();
			format.setEncoding("UTF-8");
			StringWriter strWtr = new StringWriter();

			XMLWriter xmlWriter = new XMLWriter(strWtr, format);
			xmlWriter.write(document);

			result = strWtr.toString();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}
}
